package com.nycreativity.elecreativity.service.impl;

import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.core.metadata.IPage
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.kotlin.KtUpdateWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.nycreativity.elecreativity.entity.dto.GoodsSpecificationDTO
import com.nycreativity.elecreativity.entity.dto.SkuSpecificationDTO
import com.nycreativity.elecreativity.entity.enums.IsDelEnum
import com.nycreativity.elecreativity.entity.param.goods.GoodsAddParam
import com.nycreativity.elecreativity.entity.param.goods.GoodsQueryParam
import com.nycreativity.elecreativity.entity.param.goods.GoodsSpecificationUpdateParam
import com.nycreativity.elecreativity.entity.param.goods.GoodsUpdateParam
import com.nycreativity.elecreativity.entity.po.Goods
import com.nycreativity.elecreativity.entity.vo.goods.GoodsVO
import com.nycreativity.elecreativity.entity.vo.goods.SkuOfGoodsVO
import com.nycreativity.elecreativity.entity.vo.user.UserVO
import com.nycreativity.elecreativity.mapper.GoodsMapper
import com.nycreativity.elecreativity.mapper.vomapper.GoodsVOMapper
import com.nycreativity.elecreativity.service.GoodsService
import com.nycreativity.elecreativity.service.SkuService
import com.nycreativity.elecreativity.util.MappingUtil
import com.nycreativity.elecreativity.util.usersession.UserContext
import org.springframework.stereotype.Service
import org.springframework.util.ObjectUtils
import java.time.LocalDateTime
import java.util.*
import javax.annotation.Resource
import kotlin.collections.ArrayList

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sxt && ttxxi
 * @since 2021-03-22
 */
@Service
class GoodsServiceImpl : ServiceImpl<GoodsMapper, Goods>(), GoodsService {

    @Resource
    lateinit var goodsMapper: GoodsMapper

    @Resource
    lateinit var goodsVOMapper: GoodsVOMapper

    @Resource
    lateinit var skuService: SkuService

    override fun queryById(id: Long): GoodsVO {
        return goodsVOMapper.selectById(id)
    }

    override fun queryAll(): List<GoodsVO> {
        return goodsVOMapper.selectList(null)
    }

    override fun queryPage(goodsQueryParam: GoodsQueryParam): IPage<GoodsVO> {
        val page = Page<GoodsVO>(goodsQueryParam.currentPage.toLong(), goodsQueryParam.pageSize.toLong())
        val queryWrapper = KtQueryWrapper(GoodsVO::class.java)
            .eq(!ObjectUtils.isEmpty(goodsQueryParam.typeId), GoodsVO::typeId, goodsQueryParam.typeId)
            .eq(!ObjectUtils.isEmpty(goodsQueryParam.brandId), GoodsVO::brandId, goodsQueryParam.brandId)
            .like(!ObjectUtils.isEmpty(goodsQueryParam.name), GoodsVO::name, goodsQueryParam.name)
        return goodsVOMapper.selectPage(page, queryWrapper)
    }

    override fun add(goodsAddParam: GoodsAddParam): Boolean {
        val goods = MappingUtil.getMappingObject(goodsAddParam, Goods::class.java)
        //检查是否合规
        val goodsSpecificationDTO = JSONObject.parseObject(goods.specification, GoodsSpecificationDTO::class.java)
        if (goodsSpecificationDTO == null || goodsSpecificationDTO.isEmpty()) {
            log.error("规格参数不正确")
            return false
        }
        goods.creator = UserContext.get()?.id
        goods.createTime = LocalDateTime.now()
        goodsMapper.insert(goods)
        return true
    }

    override fun updateById(goodsUpdateParam: GoodsUpdateParam): Boolean {
        val goods = MappingUtil.getMappingObject(goodsUpdateParam, Goods::class.java)
        if (goods == null || goods.isEmpty()) {
            return false
        }
        goods.modifier = UserContext.get()?.id
        goods.modifyTime = LocalDateTime.now()
        goodsMapper.updateById(goods)
        return true
    }

    override fun deleteById(id: Long): Boolean {
        val goodsList = skuService.queryByGoodsId(id)
        if (!goodsList.isEmpty()) {
            log.error("id为${id}的goods仍有sku存在，不得删除")
            return false
        }
        val wrapper = KtUpdateWrapper(Goods::class.java)
            .set(Goods::isDel, IsDelEnum.YES.code)
            .set(Goods::modifier, UserContext.get()?.id)
            .set(Goods::modifyTime, LocalDateTime.now())
            .eq(Goods::id, id)
        goodsMapper.update(null, wrapper)
        return true
    }

    override fun updateSpecificationById(param: GoodsSpecificationUpdateParam) {
        //获取对应的goods
        val goods = goodsMapper.selectById(param.goodsId) ?: throw RuntimeException("goodsId错误")
        //将goods的specification反序列化
        var goodsSpecificationDTO = JSONObject.parseObject(goods.specification, GoodsSpecificationDTO::class.java)
        //初始化
        if (goodsSpecificationDTO == null) {
            goodsSpecificationDTO = GoodsSpecificationDTO()
        }
        if (goodsSpecificationDTO.color == null) {
            goodsSpecificationDTO.color = ArrayList<String>()
        }
        if (goodsSpecificationDTO.size == null) {
            goodsSpecificationDTO.size = ArrayList<String>()
        }

        //===================针对不同场景分别处理=========================

        when (param.mode) {
            //增加target的规格
            0 -> updateTarget(param, goodsSpecificationDTO, goods)
            //删除target的规格
            1 -> deleteTarget(param, goodsSpecificationDTO, goods)
            //修改target的规格
            2 -> updateTarget(param, goodsSpecificationDTO)
        }
    }

    private fun updateTarget(param: GoodsSpecificationUpdateParam, goodsSpecificationDTO: GoodsSpecificationDTO) {
        if (param.newOne == null || param.oldOne == null) {
            throw RuntimeException("参数为空")
        }
        if (!goodsSpecificationDTO.size!!.contains(param.oldOne)) {
            throw RuntimeException("请检查旧值参数")
        }
        if (goodsSpecificationDTO.size!!.contains(param.newOne)) {
            throw RuntimeException("新值规格重复")
        }

        skuService.updateSpecificationByGoodsId(param.target!!, param.goodsId!!, param.oldOne!!, param.newOne!!)
    }

    private fun deleteTarget(
        param: GoodsSpecificationUpdateParam,
        goodsSpecificationDTO: GoodsSpecificationDTO,
        goods: Goods
    ) {
        if (param.newOne == null) {
            throw RuntimeException("参数为空")
        }

        //判断是否仍然有sku是这个规格
        val skuSpecificationDTO = SkuSpecificationDTO()
        when (param.target) {
            0 -> skuSpecificationDTO.size = param.newOne
            1 -> skuSpecificationDTO.color = param.newOne
            else -> {
                log.error("target不合法")
                throw RuntimeException("target不合法")
            }
        }
        //检查是否还有sku是这个规格，有则不能删除
        val checkSku = skuService.queryByGoodsIdAndSpecification(param.goodsId!!, skuSpecificationDTO)
        if (checkSku != null && checkSku.isNotEmpty()) {
            throw RuntimeException("该规格下仍有sku，无法删除")
        }

        goodsSpecificationDTO.size!!.remove(param.oldOne)
        goods.specification = JSONObject.toJSONString(goodsSpecificationDTO)
        goods.modifier = UserContext.get().id
        goods.modifyTime = LocalDateTime.now()
        goodsMapper.updateById(goods)
    }

    private fun updateTarget(
        param: GoodsSpecificationUpdateParam,
        goodsSpecificationDTO: GoodsSpecificationDTO,
        goods: Goods
    ) {
        if (param.newOne == null) {
            throw RuntimeException("参数为空")
        }
        if (goodsSpecificationDTO.size!!.contains(param.newOne)) {
            throw RuntimeException("规格重复")
        }

        when (param.target) {
            0 -> goodsSpecificationDTO.size!!.add(param.newOne!!)
            1 -> goodsSpecificationDTO.color!!.add(param.newOne!!)
            else -> {
                log.error("target不合法")
                throw RuntimeException("target不合法")
            }
        }
        goods.specification = JSONObject.toJSONString(goodsSpecificationDTO)
        goods.modifier = UserContext.get().id
        goods.modifyTime = LocalDateTime.now()
        goodsMapper.updateById(goods)
    }


}
